/*
 * Copyright (C) 2009 CodeWerkz
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.codewerkz.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;


/**
 * SettingsLoader: An object that can be created and will load
 * settings from a preferences file aswell as save them and thier
 * values.
 * 
 * @author ChaZ
 */
public class SettingsLoader {	
	
	// Context and Tags.
	private final Context mCtx;
	private static final String TAG = "Prompty - SettingsLoader";
	
	// Member Enumerators for each Setting handled.
	public static enum FontSize { DEFAULT, LARGE, SMALL };
	public static enum WelcomeMessage {	ENABLED, DISABLED };
	
	// Member settings to store the setting.
	private static FontSize sFontSize;
	private static WelcomeMessage sWelcomeMessage;
	private static boolean sFirstRun;
	
	// Static preferences file.
	private static final String PREFERENCE_FILE = "PromptyPreferencesFile";
	
	/**
	 *  Interface: Make sure user implements load settings.
	 */
	public interface LoadSettings {
		abstract void loadSettings();
	}
	
	/**
	 * Constructor
	 * 
	 * @param ctx Context
	 */
	public SettingsLoader(Context ctx) {
		// Get the context from the Activity calling and initialise other variables to defaults.
		this.mCtx = ctx;
		SettingsLoader.sFontSize = FontSize.DEFAULT;
		SettingsLoader.sWelcomeMessage = WelcomeMessage.ENABLED;
		
		// Load the preferences file.
		if(!loadPreferences()) {
			Log.e(TAG, "Load Preferences failed. Critical error.");
		}
	}
	
	/**************************************
	 * GETTERS & SETTERS for each setting. 
	 **************************************/
	// Getters: Font Size
	public float getFontSize() {
		return this.fontEnumToPx(SettingsLoader.sFontSize);
	}
	
	public String getFontSize_string() {
		if( SettingsLoader.sFontSize == FontSize.DEFAULT) {
			return "Default";
		}
		else if ( SettingsLoader.sFontSize == FontSize.LARGE) {
			return "Large";
		}
		else {
			return "Small";
		}
	}
	
	public int getFontSize_integer() {
		if( SettingsLoader.sFontSize == FontSize.DEFAULT) {
			return 0;
		}
		else if ( SettingsLoader.sFontSize == FontSize.LARGE) {
			return 1;
		}
		else {
			return -1;
		}
	}
	
	// Setters: Font Size
	public void setFontSize(FontSize newFontSize) {
		SettingsLoader.sFontSize = newFontSize;
	}
	
	public void setFontSize(Integer newFontSize) throws Exception {
		switch( newFontSize ) {
			case -1:
				SettingsLoader.sFontSize = FontSize.SMALL;
				break;
				
			case 0:
				SettingsLoader.sFontSize = FontSize.DEFAULT;
				break;
				
			case 1:
				SettingsLoader.sFontSize = FontSize.LARGE;
				break;
				
			default:
				SettingsLoader.sFontSize = FontSize.DEFAULT;
				throw new Exception("Font Size must either be -1, 0, or 1. You sent: " + Integer.toString(newFontSize));
		}
	}
	
	public void setFontSize(String newFontSize) throws Exception {
		if( newFontSize == "Default") {
			SettingsLoader.sFontSize = FontSize.DEFAULT;
		}
		else if (newFontSize == "Large") {
			SettingsLoader.sFontSize = FontSize.LARGE;
		}
		// Small
		else if (newFontSize == "Small") {
			SettingsLoader.sFontSize = FontSize.SMALL;
		}
		else {
			SettingsLoader.sFontSize = FontSize.DEFAULT;
			throw new Exception("Font Size must be either Small, Default or Large. You sent: " + newFontSize);
		}
	}
	
	// Getters: Welcome Message.
	public boolean isWelcomeMessageEnabled () {
		switch (SettingsLoader.sWelcomeMessage)	{
			case ENABLED:
				return true;
			case DISABLED:
				return false;
			default:
				return false;
		}
	}
	
	// Setters: Welcome Message.
	public void setWelcomeMessageEnabled(boolean enabled) {
		if ( enabled ) {
			SettingsLoader.sWelcomeMessage = WelcomeMessage.ENABLED;
		} else {
			SettingsLoader.sWelcomeMessage = WelcomeMessage.DISABLED;
		}
	}
	
	// Getters: First Run
	public boolean isFirstRun() {
		return SettingsLoader.sFirstRun;
	}
	
	// Setters: First Run
	public void setFirstRun(boolean firstRun) {
		SettingsLoader.sFirstRun = firstRun;
	}
	
	/**
	 * Loads all the preferences.
	 * 
	 * @return boolean Returns true if loaded without error.
	 */
	public boolean loadPreferences () {
		// Load the preferences from disk
		SharedPreferences settings = mCtx.getSharedPreferences(SettingsLoader.PREFERENCE_FILE, 0);
		
		// Set values from file to our object
		try	{
			int fontSize = settings.getInt("fontSize", 0);
			this.setFontSize(fontSize);
			Log.v(TAG, "Set up font: " + Integer.toString(fontSize));
			
			boolean welcomeMessage = settings.getBoolean("welcomeMessage", true);
			this.setWelcomeMessageEnabled(welcomeMessage);
			Log.v(TAG, "Set up WelcomeEnabled: " + Boolean.toString(welcomeMessage));
			
			boolean firstRun = settings.getBoolean("firstRun", true);
			this.setFirstRun(firstRun);
			
			return true;
		} catch ( Exception e) {
			Log.e(TAG, e.getMessage());
			return false;
		}
	}
	
	/**
	 * Saves preferences to file.
	 * 
	 * @return boolean Returns true if saved fine.
	 */
	public boolean savePreferences () {
		SharedPreferences settings = mCtx.getSharedPreferences(SettingsLoader.PREFERENCE_FILE, 0);
		SharedPreferences.Editor editor = settings.edit();
		
		// Set our settings.
		editor.putInt("fontSize", this.getFontSize_integer());
	    editor.putBoolean("welcomeMessage", this.isWelcomeMessageEnabled());
	    editor.putBoolean("firstRun", this.isFirstRun());

	    // Don't forget to commit your edits!!!
	    if(editor.commit())
	    {
	    	return true;	    	
	    }
	    return false;	
	}
	
	/**
	 * Converts the Font Enum to an actual value in COMPLEX_UNIT_PX.
	 * 
	 * @param fontSize
	 * @return float
	 */
	public float fontEnumToPx(FontSize fontSize) {
		switch(fontSize) {
			case DEFAULT:
				return 12f;
			case LARGE:
				return 16f;
			case SMALL:
				return 10f;
			default:
				return 12f;
		}
	}
	
	/**
	 * Destructor method.
	 * 
	 * @return void
	 */
	protected void finalize() throws Throwable
	{
	  this.savePreferences();
	  
	  super.finalize(); //not necessary if extending Object.
	}
}
